package db

import (
	"gitee.com/yysf-xin/dproxy/pkg/model"
	"gitee.com/yysf-xin/dproxy/pkg/rest"
	"gitee.com/yysf-xin/dproxy/pkg/tools"
	"gorm.io/gorm"
	"net/http"
	"net/url"
	"strings"
)

type Tunnel struct {
	model.Model
	model.State
	Name   string `gorm:"size:64"`
	Local  string `gorm:"size:128"`
	Target string `gorm:"size:128"`
	model.Enable
}

func (t *Tunnel) CustomFlag() uint8 {
	return rest.DELETE | rest.GET | rest.LIST
}

func (t *Tunnel) TableName() string {
	return "tunnel"
}

type TcpForward struct {
	model.Model
	model.State
	Name  string `gorm:"size:128"`
	SrcIp string `gorm:"size:128"`
	TarIp string `gorm:"size:128"`
	model.Enable
}

func (t *TcpForward) CustomFlag() uint8 {
	return rest.DELETE
}

func (t *TcpForward) TableName() string {
	return "tcp_forward"
}

type SshServer struct {
	model.Model
	model.State
	Name   string `gorm:"size:128"`
	Remote string `gorm:"size:128"`
	IdRsa  string `gorm:"size:2500"`
	model.Enable
}

func (s *SshServer) BeforeCreate(tx *gorm.DB) (err error) {
	return s.Encrypt(tx)
}

func (s *SshServer) BeforeUpdate(tx *gorm.DB) (err error) {
	return s.Encrypt(tx)
}

func (s *SshServer) Decrypt(tx *gorm.DB) (err error) {
	if s.IdRsa != "" {
		cipher := tx.Plugins["cipher"].(*CipherPlugin)
		data, err := cipher.DecryptBase64(s.IdRsa)
		if err == nil {
			s.IdRsa = string(data)
			if tx.Statement != nil {
				tx.Statement.SetColumn("id_rsa", s.IdRsa, true)
			}
		}
	}
	return
}

func (s *SshServer) Encrypt(tx *gorm.DB) (err error) {
	if s.IdRsa != "" {
		cipher := tx.Plugins["cipher"].(*CipherPlugin)
		s.IdRsa, err = cipher.EncryptToBase64([]byte(s.IdRsa))

		if tx.Statement != nil {
			tx.Statement.SetColumn("id_rsa", s.IdRsa, true)
		}
	}
	return
}
func (s *SshServer) CustomFlag() uint8 {
	return rest.LIST | rest.GET
}

func (s *SshServer) TableName() string {
	return "ssh_server"
}

type Proxy struct {
	model.Model
	URL      string `gorm:"size:128"`
	Type     int
	HasAuth  bool
	UserName string `gorm:"size:128"`
	Password string `gorm:"size:128"`
	model.Enable
	ProxyURL *url.URL `gorm:"-" json:"-"`
}

func (p *Proxy) CustomFlag() uint8 {
	return rest.DELETE
}

func (p *Proxy) TableName() string {
	return "proxy"
}

// RouteRule 路由规则
type RouteRule struct {
	model.Model
	Host    string `gorm:"size:128"`
	Service string `gorm:"size:128"`
	model.Enable
	IntId uint64 `gorm:"-" json:"-"`
}

func (r *RouteRule) TableName() string {
	return "route_rule"
}

type LocalServer struct {
	model.Model
	model.State
	Host      string `gorm:"size:128"`
	Path      string `gorm:"size:128"`
	Target    string `gorm:"size:128"`
	Enabled   bool
	TargetURL *url.URL `gorm:"-" json:"-"`
}

func (l *LocalServer) CustomFlag() uint8 {
	return rest.GET | rest.DELETE
}

func (l *LocalServer) TableName() string {
	return "local_server"
}

func (l *LocalServer) Director(req *http.Request) {
	req.Host = l.TargetURL.Host
	req.URL.Host = l.TargetURL.Host
	req.URL.Scheme = l.TargetURL.Scheme
	if strings.HasSuffix(l.Target, "/") {
		req.URL.Path = tools.SingleJoiningSlash(l.TargetURL.Path, req.URL.Path[len(l.Path):])
	} else {
		req.URL.Path = tools.SingleJoiningSlash(l.Path, req.URL.Path)
	}
}

type ProxyPass struct {
	model.Model
	Name   string `gorm:"size:128"`
	Domain string `gorm:"size:128"`
	Path   string `gorm:"size:128"`
	Target string `gorm:"size:128"`

	ChangeOrigin bool

	model.Enable
	TargetURL *url.URL `gorm:"-" json:"-"`
}

func (p *ProxyPass) TableName() string {
	return "proxy_pass"
}

type TurnClient struct {
	model.Model
	Name     string `gorm:"size:128"`
	Endpoint string `gorm:"size:256"`
	model.State
	model.Enable
	EndpointURL *url.URL `gorm:"-" json:"-"`
}

func (t *TurnClient) CustomFlag() uint8 {
	return rest.GET | rest.LIST | rest.DELETE
}

func (t *TurnClient) TableName() string {
	return "turn_client"
}

type TurnGroup struct {
	model.Model
	Name string `gorm:"size:128"`
	model.Enable
}

func (t *TurnGroup) TableName() string {
	return "turn_group"
}

//type TurnServer TurnClient
//func (t *TurnServer) TableName() string {
//	return "turn_server"
//}
